﻿using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;
using ff14bot;
using ff14bot.Behavior;
using ff14bot.Enums;
using ff14bot.Helpers;
using ff14bot.Managers;
using TreeSharp;
using ff14bot.AClasses;
using Magitek.Settings;

using Action = TreeSharp.Action;
using Magitek.Helpers;

//    First of all, big thanks to Mastagh, this custom routine is essentially a rehash of Kupo and wouldn't have been possible without it.
//    Thank you for reporting errors and improving Magitek.

namespace Magitek
{
        public abstract class Magitek : CombatRoutine
        {
            #region Necessary Stuff
            public override string Name { get { return "Magitek"; } }
            private Composite Root;
            public static MagitekSettings WindowSettings = MagitekSettings.Instance;
            public Target targeting = new Target();
            public sealed override void Pulse()
            {
                #region Composite Root
                try
                {
                    Root.Tick(null);
                    if (Root.LastStatus != RunStatus.Running)
                    {
                        Root.Stop(null);
                        Root.Start(null);
                    }
                }
                catch (Exception e)
                {
                    Logging.WriteException(e);
                    Root.Stop(null);
                    Root.Start(null);
                    throw;
                }
                #endregion

                OnPulse();
            
                Extensions.DoubleCastPreventionDict.RemoveAll(t => DateTime.UtcNow > t);
                Extensions.HealDoubleCastPreventionDict.RemoveAll(t => DateTime.UtcNow > t);
            

                if (WindowSettings.AutoTarget)
                {
                    if (!GameSettingsManager.FaceTargetOnAction)
                        GameSettingsManager.FaceTargetOnAction = true;

                    targeting.GetTarget();
                }

            }
            public virtual void OnPulse() { }
            public Composite TreeSharpPulse()
            {
                return new PrioritySelector(

                    OnTreeSharpPulse()

                    );
            }
            public virtual Composite OnTreeSharpPulse()
            {
                return new PrioritySelector(

                    Extensions.AcceptRaise,
                    Items.Use(WindowSettings.foodname, true)

                    );                
            }
            public override void Initialize()
            {
                HotkeyManager.Register("AOE Key", WindowSettings.AOEKeyChoice, WindowSettings.AOEModKeyChoice, hk => { WindowSettings.AOEEnabled = !WindowSettings.AOEEnabled; Logging.Write(WindowSettings.AOEEnabled ? "[Magitek] AOE Mode Enabled" : "[Magitek] AOE Mode Disabled"); });

                if (WindowSettings.WarriorToggleMode)
                {
                    HotkeyManager.Register("Warrior Rotation", Keys.None, ModifierKeys.Control, hk =>
                    {
                        WindowSettings.WarriorDPSRotation = !WindowSettings.WarriorDPSRotation;
                        Logging.Write(WindowSettings.WarriorDPSRotation
                            ? "[Magitek] Warrior DPS rotation enabled"
                            : "[Magitek] Warrior threat rotation enabled");
                    });
                }


                WindowSettings.AOEEnabled = false;
                Root = TreeSharpPulse();
                Root.Start(null);

            }
            public override void ShutDown()
            {
                HotkeyManager.Unregister("AOE Key");
                HotkeyManager.Unregister("Warrior Rotation");
            }
            #endregion
            #region Form Stuff
            public override bool WantButton { get { return true; } }
            private Form _form;

            public override void OnButtonPress()
            {
                if (_form == null || _form.IsDisposed || _form.Disposing)
                    _form = new SettingsForm();

                _form.ShowDialog();                
            }
            #endregion  
            #region Hooks & Things
            private Composite _heal, _combat, _preCombatbuffs, _combatbuffs, _pull, _rest;

            public sealed override Composite HealBehavior { get { return _heal ?? (_heal = CreateHeal()); } }
            public sealed override Composite RestBehavior { get { return _rest ?? (_rest = CreateRest()); } }
            public sealed override Composite CombatBehavior { get { return _combat ?? (_combat = CreateCombat()); } }
            public sealed override Composite PreCombatBuffBehavior { get { return _preCombatbuffs ?? (_preCombatbuffs = CreatePreCombatBuffs()); } }
            public sealed override Composite CombatBuffBehavior { get { return _combatbuffs ?? (_combatbuffs = CreateCombatBuffs()); } }
            public sealed override Composite PullBehavior { get { return _pull ?? (_pull = CreatePull()); } }


            protected virtual Composite CreateCombat()
            {       
                return new HookExecutor("Magitek_Combat_Root",
                    "Root composite for Magitek combat. Rotations will be plugged into this hook.",
                    new Action(r => RunStatus.Failure));
            }

            protected virtual Composite CreateRest()
            {
                return new HookExecutor("Magitek_Rest_Root",
                    "Root composite for Magitek Rest. Rotations will be plugged into this hook.",
                    new Action(r => RunStatus.Failure));
            }

            protected virtual Composite CreatePreCombatBuffs()
            {
                return new HookExecutor("Magitek_PreCombatBuffs_Root",
                    "Root composite for Magitek buffs. Rotations will be plugged into this hook.",
                    new Action(r => RunStatus.Failure));
            }

            protected virtual Composite CreateCombatBuffs()
            {
                return new HookExecutor("Magitek_CombatBuffs_Root",
                    "Root composite for Magitek buffs. Rotations will be plugged into this hook.",
                    new Action(r => RunStatus.Failure));
            }

            protected virtual Composite CreateHeal()
            {
                return new HookExecutor("Magitek_Heals_Root",
                    "Root composite for Magitek heals. Rotations will be plugged into this hook.",
                    new Action(r => RunStatus.Failure));
            }

            protected virtual Composite CreatePull()
            {
                return new HookExecutor("Magitek_Pull_Root",
                    "Root composite for Magitek pull. Rotations will be plugged into this hook.",
                    new Action(r => RunStatus.Failure));
            }
            #endregion
        }
}